#include <onix/types.h>

/**
 * 安全的 memmove 实现
 *
 * @param dest 目标缓冲区指针
 * @param src  源缓冲区指针
 * @param n    要移动的字节数
 * @return     返回目标缓冲区指针，如果输入无效则返回 NULL
 */
void* memmove(void* dest, const void* src, size_t n) {
    // 检查指针是否为 NULL
    if (dest == NULL || src == NULL) {
        return NULL;
    }

    // 如果源和目标相同，或者 n 为 0，无需移动
    if (dest == src || n == 0) {
        return dest;
    }

    unsigned char* d = (unsigned char*) dest;
    const unsigned char* s = (const unsigned char*) src;

    // 判断内存块是否重叠
    if (d < s) {
        // 从前往后拷贝
        for (size_t i = 0; i < n; i++) {
            d[i] = s[i];
        }
    } else {
        // 从后往前拷贝
        // 注意避免 size_t 在减法时下溢
        for (size_t i = n; i != 0; i--) {
            d[i-1] = s[i-1];
        }
    }

    return dest;
}